<template>
	<div
		:class="{
			'app-control-form__druipart': true,
			[`app-control-form__druipart__${name}`]: true,
		}"
	>
		<component
			openType="EMBED"
			class="view-container2"
			:is="viewName"
			:name="viewName"
			:context="drContext"
			:viewParams="drViewParams"
			:isLoadDefault="false"
			@view-action="(name: string, action: IEvent<string>, data: IParam) => { handleViewAction(name, action, data); }"
			@view-init="(name: string, data: IViewAbility) => { handleViewInit(name, data); }"
			@view-mounted="(name: string, data: IParam) => { handleViewMounted(name, data); }"
			@view-destroy="(name: string, data: IParam) => { handleViewDestroy(name, data); }"
		/>
		<div v-if="blockUI" class="app-control-form__druipart__mask">
			<div class="druipart__mask__tooltip">
				{{ $t('widget.editform.formdruipart') }}
			</div>
		</div>
	</div>
</template>
<script setup lang="ts">
import {
	IEvent,
	computedNavData,
	IParam,
	IViewAbility,
	IViewDetail,
	formatAppDERSPath,
	deepCopy,
} from '@/core';
import { Ref } from 'vue';
import { formDruipartProps } from '../form';
const props = defineProps(formDruipartProps);
interface ComponentEmit {
	(name: 'component-action', value: IEvent<string>): void;
}
const emit = defineEmits<ComponentEmit>();
// 关系界面上下文
const drContext: Ref<any> = ref({});
// 关系界面视图参数
const drViewParams: Ref<any> = ref({});
// 是否启用遮罩
const blockUI: Ref<boolean> = ref(false);
// 刷新节点
let hookItems: any[] = [];
// 关系界面能力
const ability = ref<IViewAbility | null>(null);
// 视图是否挂载
let viewIsMounted: boolean = false;

const refreshDRUIPart = (data: IParam, action: string) => {
	const formData = data ? data : props.data;
	const _paramItem = formData[props.paramItem];
	let tempContext: any = {};
	let tempParam: any = {};
	const viewConfig: IViewDetail = App.getAppViewConfig()[props.viewName];
	const deResParameters = formatAppDERSPath(
		props.context,
		viewConfig.appDERSPaths
	);
	deResParameters.forEach((parameter: any) => {
		if (formData[parameter.parameterName]) {
			Object.assign(tempContext, {
				[parameter.parameterName]: formData[parameter.parameterName],
			});
		}
	});
	Object.assign(tempContext, { [props.paramItem]: _paramItem });
	//设置顶层视图唯一标识
	Object.assign(tempContext, props.context);
	Object.assign(tempContext, {
		srfparentdename: props.parentName,
		srfparentkey: _paramItem,
	});
	Object.assign(tempParam, {
		srfparentdename: props.parentName,
		srfparentkey: _paramItem,
	});
	// 设置局部上下文
	if (props.localContext && Object.keys(props.localContext).length > 0) {
		let _context: any = computedNavData(
			formData,
			tempContext,
			props.viewParams,
			props.localContext
		);
		Object.assign(tempContext, _context);
	}
	drContext.value = tempContext;
	// 设置局部参数
	if (props.localViewParams && Object.keys(props.localViewParams).length > 0) {
		let _param: any = computedNavData(
			formData,
			tempContext,
			props.viewParams,
			props.localViewParams
		);
		Object.assign(tempParam, _param);
	}
	if (props.viewParams.hasOwnProperty('copymode')) {
		Object.assign(tempParam, { copymode: props.viewParams.copymode });
	}
	drViewParams.value = tempParam;
	// 从数据模式无遮罩层
	if (props.isRelationalData) {
		if (props.tempMode == 2) {
			blockUI.value = false;
		} else {
			if (
				!_paramItem ||
				(/[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}/.test(
					_paramItem
				) &&
					formData['srfuf'] == '0') ||
				(Object.is('showBlock', props.userTag2) && formData['srfuf'] == '0')
			) {
				blockUI.value = true;
				return;
			} else {
				blockUI.value = false;
			}
		}
	}
	if (Object.is(props.userTag, 'alwaysLoad') || formData['srfuf'] != '0') {
		try {
			if (ability.value) {
				if (action == 'refresh') {
					ability.value.refresh();
				}
			}
		} catch (error: any) {}
	}
};

const loadDRUIPart = () => {
	if (ability.value) {
		const tempViewParams = deepCopy(drViewParams.value);
		ability.value.load(tempViewParams);
	}
};

const saveDRUIPart = (data: IParam) => {
	try {
		if (props.tempMode && props.tempMode == 2) {
			if (ability.value) {
				ability.value.save();
			}
		} else {
			if (data && !Object.is(data.srfuf, '0')) {
				if (ability.value) {
					ability.value.save();
				}
			} else {
				emit('component-action', {
					name: props.name,
					action: 'viewDataSave',
					data: { type: 'DRUIPART' },
				});
			}
		}
	} catch (error: any) {}
};

const handleFormValueChange = (data: IParam) => {
	let refreshRefView = false;
	Object.keys(data).some((name: string) => {
		const index = hookItems.findIndex((_name: string) =>
			Object.is(_name, name)
		);
		refreshRefView = index !== -1 ? true : false;
		return refreshRefView;
	});
	if (refreshRefView) {
		refreshDRUIPart(data, 'refresh');
	}
};

const initDruipart = () => {
	refreshDRUIPart(props.data, 'load');
	hookItems = [...props.refreshItems.split(';')];
	if (!Object.is(props.paramItem, props.parentName.toLowerCase())) {
		hookItems.push(props.paramItem);
	}
	const executeFormDetail = ({ name, action, data }: IEvent<string>) => {
		switch (action) {
			case 'load':
				refreshDRUIPart(data, 'load');
				// 新建表单不加载关系界面
				if (viewIsMounted && data['srfuf'] != '0') {
					loadDRUIPart();
				}
				break;
			case 'save':
				refreshDRUIPart(data, 'refresh');
				break;
			case 'beforeSave':
				saveDRUIPart(data);
				break;
			case 'valueChange':
				handleFormValueChange(data);
				break;
			default:
				break;
		}
	};
	emit('component-action', {
		name: props.name,
		action: 'componentInit',
		data: { executeFormDetail: executeFormDetail },
	});
};

initDruipart();

const handleViewAction = (
	name: string,
	action: IEvent<string>,
	data: IParam
) => {
	if (Object.is(action, 'viewDataSave')) {
		emit('component-action', {
			name: props.name,
			action: 'viewDataSave',
			data: { type: 'DRUIPART' },
		});
	}
};
const handleViewInit = (name: string, viewAbility: IViewAbility) => {
	ability.value = viewAbility;
};

const handleViewMounted = (name: string, data: IParam) => {
	viewIsMounted = true;
	if (props.isLoaded) {
		loadDRUIPart();
	}
};
const handleViewDestroy = (name: string, data: IParam) => {
	console.log('视图销毁', name, data);
};
</script>
